/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_orm.htm
 *
 * Zhiqim ORM is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.orm;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

import org.zhiqim.kernel.service.MultiInstance;
import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.model.maps.LinkedMapSO;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.kernel.model.maps.MapSS;
import org.zhiqim.kernel.paging.PageResult;
import org.zhiqim.orm.dbo.Selector;
import org.zhiqim.orm.dbo.Updater;
import org.zhiqim.orm.dbo.defined._Table;

/**
 * 自建表与数据库表映射调用
 *
 * @version v1.0.0 @author zouzhigang 2016-10-26 新建与整理
 */
@AnAlias("ZTab")
public interface ZTab extends MultiInstance
{
    /**************************************************************************/
    //exists 表是否存在
    /**************************************************************************/
    
    /**
     * 是否存在[实际表]可替换表
     * 
     * @param table         表类
     * @return              =true表示存在，=false表示不存在
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public boolean exists(_Table _table) throws ORMException, SQLException;
    
    /**
     * 是否存在[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param table         表类
     * @param replaceMap    可替换字段表
     * @return              =true表示存在，=false表示不存在
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public boolean exists(_Table table, MapSS replaceMap) throws ORMException, SQLException;
    
    /**************************************************************************/
    //create 创建表
    /**************************************************************************/
    
    /**
     * 创建[实际表]可替换表，正常创建检查
     * 
     * @param _table        表类
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table) throws ORMException, SQLException;
    
    /**
     * 创建[实际表]可替换表，正常创建检查，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表类
     * @param replaceMap    可替换字段表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table, MapSS replaceMap) throws ORMException, SQLException;
    
    /**
     * 创建[实际表]可替换表
     * 
     * @param _table        表类
     * @param isException   是否异常重建
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table, boolean isException) throws ORMException, SQLException;
    
    /**
     * 创建[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表类
     * @param replaceMap    可替换字段表
     * @param isException   是否异常重建
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table, MapSS replaceMap, boolean isException) throws ORMException, SQLException;
    
    /**************************************************************************/
    //drop 删除表
    /**************************************************************************/
    
    /**
     * 删除[实际表]可替换表
     * 
     * @param _table        表类
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void drop(_Table _table) throws ORMException, SQLException;
    
    /**
     * 删除[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表类
     * @param replaceMap    可替换字段表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void drop(_Table _table, MapSS replaceMap) throws ORMException, SQLException;
    
    /**************************************************************************/
    //truncate 清空表
    /**************************************************************************/
    
    /**
     * 清空[实际表]
     * 
     * @param _table        表对象
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void truncate(_Table _table) throws ORMException, SQLException;
    
    /**
     * 清空[实际表]，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表对象
     * @param replaceMap    替换表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void truncate(_Table _table, MapSS replaceMap) throws ORMException, SQLException;
    
    /**************************************************************************/
    //insert 插入数据
    /**************************************************************************/
    
    /**
     * 增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表数据对象
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insert(_Table _table, LinkedMapSO data) throws ORMException, SQLException;
    
    /**
     * 增加数据，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表类
     * @param month         月份
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insertMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException;
    
    /**
     * 增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表数据对象
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insert(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException;
    
    /**
     * 替换数据,传入标准[表类]对象和更新器（取fieldMap和replaceMap）当存在时指定修改的值
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param updater       更新器
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insertOrUpdate(_Table _table, LinkedMapSO data, Updater updater) throws ORMException, SQLException;
    
    /**
     * 批量增加数据
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] insertBatch(_Table _table, List<LinkedMapSO> dataList) throws ORMException, SQLException;
    
    /**
     * 批量增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] insertBatch(_Table _table, List<LinkedMapSO> dataList, MapSS replaceMap) throws ORMException, SQLException;
    
    
    /**************************************************************************/
    //replace 替换数据，MYSQL支持，如果有数据先删除后增加
    /**************************************************************************/
    
    /**
     * 替换数据,传入标准[表类]对象
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data) throws ORMException, SQLException;

    /**
     * 替换数据，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param month         月份
     * @return int          表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replaceMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException;
    
    /**
     * 替换数据，支持表或字段中有一个替换字段，如LOG_TRACE$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceKey    替换键
     * @param replaceValue  替换值
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data, String replaceKey, String replaceValue) throws ORMException, SQLException;
    
    /**
     * 替换数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException;

    /**
     * 批量替换数据
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] replaceBatch(_Table _table, List<LinkedMapSO> dataList) throws ORMException, SQLException;
    
    /**
     * 批量替换数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] replaceBatch(_Table _table, List<LinkedMapSO> dataList, MapSS replaceMap) throws ORMException, SQLException;
    
    /**************************************************************************/
    //update 更新数据
    /**************************************************************************/
    
    /**
     * 更新数据，指定更新器需要更新的字段、条件和可替换表
     * 
     * @param _table        表定义对象
     * @param updater       更新器
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, Updater updater) throws ORMException, SQLException;
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data) throws ORMException, SQLException;
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param month         月份
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int updateMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException;
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持表或字段中有一个替换字段，如LOG_TRACE$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceKey    替换键
     * @param replaceValue  替换值
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data, String replaceKey, String replaceValue) throws ORMException, SQLException;
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持可替换表
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceMap    适配表
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException;
    
    /**************************************************************************/
    //delete 删除数据
    /**************************************************************************/
    
    /**
     * 删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param ids           关键属性为数组，多个主键
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, Object... ids) throws ORMException, SQLException;
    
    /**
     * 删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param replaceMap    替换表
     * @param ids           关键属性为数组，多个主键
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, MapSS replaceMap, Object... ids) throws ORMException, SQLException;
    
    /**
     * 删除数据, 根据条件
     * 
     * @param _table        表定义对象
     * @param selector      对象选择器
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, Selector selector) throws ORMException, SQLException;
    
    /**
     * 批量删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param idsList       关键属性为数组，多个主键的列表
     * @return              返回删除数列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] deleteBatch(_Table _table, List<Object[]> idsList) throws ORMException, SQLException;
    
    /**
     * 批量删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param replaceMap    替换表
     * @param idsList       关键属性为数组，多个主键的列表
     * @return              返回删除数列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] deleteBatch(_Table _table, MapSS replaceMap, List<Object[]> idsList) throws ORMException, SQLException;
    
    /**************************************************************************/
    //count 查询数目
    /**************************************************************************/
    
    /**
     * 查询数目，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param ids           关键属性值，支持多个
     * @return              存在的数目
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table, Object... ids) throws ORMException, SQLException;

    /**
     * 查询数目，整表查询
     * 
     * @param _table        表定义对象
     * @return              int 数目值
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table) throws ORMException, SQLException;
    
    /**
     * 查询数目，根据条件、可替换表查询
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @return              int 数目值
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table, Selector selector)throws ORMException, SQLException;
    
    /**
     * 分组查询数目，根据条件、可替换表和分组字段
     * 
     * @param cls           表类
     * @param selector
     * @return
     * @throws ORMException
     * @throws SQLException
     */
    public List<MapSO> countGroupBy(_Table _table, Selector selector) throws ORMException, SQLException;
    
    /**************************************************************************/
    //sum 计算总和
    /**************************************************************************/
    
    /**
     * 计算总和
     * 
     * @param _table        表定义对象
     * @param field         表字段
     * @return              计算总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public BigDecimal sum(_Table _table, String field) throws ORMException, SQLException;
    
    /**
     * 计算总和
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @param field         表字段
     * @return              计算总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public BigDecimal sum(_Table _table, Selector selector, String field) throws ORMException, SQLException;
    
    /**
     * 计算多个总和
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @param fields        多个表字段
     * @return              计算多个总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public List<BigDecimal> sum(_Table _table, Selector selector, String... fields) throws ORMException, SQLException;
    
    /**************************************************************************/
    //item 查询一条数据
    /**************************************************************************/
    
    /**
     * 查询一个表对象，支持多个主键
     * 
     * @param _table        表定义实例
     * @param ids           关键属性值
     * @return              返回表对象
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table, Object... ids) throws ORMException, SQLException;
    
    /**
     * 查询一个表对象，并指定返回属性,查询第一行
     * 
     * @param _table        表定义实例
     * @return              返回表对象
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table) throws ORMException, SQLException;
    
    /**
     * 查询一个表对象，并指定返回属性,查询条件和排序条件
     * 
     * @param _table        表定义实例
     * @param selector      对象查询器
     * @return              返回表对象
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table, Selector selector) throws ORMException, SQLException;
    
    /**************************************************************************/
    //list 查询列表
    /**************************************************************************/
    
    /**
     * 查询表对象列表，全表查询
     * 
     * @param _table        表定义对象
     * @return              返回表对象列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table) throws ORMException, SQLException;
    
    /**
     * 查询表对象列表，并指定返回属性,查询条件和排序条件
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @return              返回表对象列表
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, Selector selector) throws ORMException, SQLException;
    
    /**
     * 查询表对象列表，查询指定的位置的数据
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @return              返回表对象列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, int pageNo, int pageSize) throws ORMException, SQLException;
    
    /**
     * 查询表对象列表，并指定位置的,条件和排序条件
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @param selector      对象查询器
     * @return              返回表对象列表
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, int pageNo, int pageSize, Selector selector) throws ORMException, SQLException;
    
    /**************************************************************************/
    //page 分页显示
    /**************************************************************************/
    
    /**
     * 查询表对象分页信息
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @return              分页信息,包括总页数,页码,页数和查询的记录
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public PageResult<LinkedMapSO> page(_Table _table, int pageNo, int pageSize) throws ORMException, SQLException;

    /**
     * 查询表对象分页信息
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @param selector      对象查询器
     * @return              分页信息,包括总页数,页码,页数和查询的记录
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public PageResult<LinkedMapSO> page(_Table _table, int pageNo, int pageSize, Selector selector) throws ORMException, SQLException;
    
    /**************************************************************************/
    //内部ZTabler & ZTable 共享的方法
    /**************************************************************************/
    
    /**
     * 通过表定义对象，组装插入或替换的SQL
     * 1.insert & insertOrUpdate & insertBatch
     * 2.replace & replaceBatch
     * 调用
     * 
     * @param _table        表定义对象
     * @param statement     insert & replace
     * @return              SQL语句
     */
    public String toInsertOrReplaceSQL(_Table _table, String statement);
    
    /**
     * 通过表定义对象，组装更新字段SQL
     * update & insertOrUpdate调用
     * 
     * @param _table        表定义对象
     * @param updater       更新器
     * @param paramMap      参数表
     * @return              SQL语句
     * @throws ORMException 映射异常
     */
    public String toUpdateFieldSQL(_Table _table, Updater updater, MapSO paramMap) throws ORMException;
}
